
#ifndef NETBASE_LISTENER_H
#define NETBASE_LISTENER_H

// sys
#include <stdint.h>
#include <functional>
#include <memory>
// mine
#include "util.h"

struct sockaddr;
struct event_base;
struct evconnlistener;

namespace net_base {
class NetBase;
class TcpSession;
typedef std::shared_ptr<TcpSession> TcpSessionPtr;

/*!
 * @brief
 *  a Listener that can accpet new tcp connections
 * @note
 *  a Listener has one underlaying evbase which is running on one of the 
 *  threads, all process of this listener and the session which is accepted
 *  later will be run on the same thread that evbase is running on.
 */
class Listener {
 public:
  typedef std::function<void (TcpSessionPtr)> NewConnCB;

 public:
  ~Listener(void);

  /*!
   * listen on specific ip/port, call cb when new connection arrived
   */
  void Listen(const char* ip, uint16_t port, const NewConnCB& cb);

  /*!
   * listen on specific ip/port, call cb when new connection arrived
   * ip_port format: 
   *  IPv4Address:port
   *  IPv4Address
   * If no port is specified, the port in the output is set to 0
   * 
   */
  void Listen(const char* ip_port, const NewConnCB& cb);

 private:
  friend class NetBase;
  Listener(event_base* evbase);

  void Listen(const sockaddr* sa, int socklen, const NewConnCB& cb);

  NONCOPYABLE(Listener);
  IMPL_DECL;
};

typedef std::unique_ptr<Listener> ListenerPtr;
} // namespace net_base

#endif // NETBASE_LISTENER_H

